﻿//
// Copyright © MixModes Inc. 2011
//

using System;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using MixModes.Phone.Synergy.Framework;
using MixModes.Phone.Synergy.ViewModels;

namespace MixModes.Phone.Synergy.Views
{
    /// <summary>
    /// Base view class
    /// </summary>
    public class ViewBase : PhoneApplicationPage, IDisposable
    {
        /// <summary>
        /// Initializes a new instance of the of the PhoneApplicationPage class.
        /// </summary>
        public ViewBase()
        {
            _isNewPageInstance = true;
            PhoneApplication phoneApplication = PhoneApplication.Instance;
            if (phoneApplication != null)
            {
                PhoneApplication.Instance.LoadSettings += OnLoadState;
                PhoneApplication.Instance.SaveSettings += OnSaveState;
            }
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            PhoneApplication phoneApplication = PhoneApplication.Instance;
            if (phoneApplication != null)
            {
                PhoneApplication.Instance.LoadSettings -= OnLoadState;
                PhoneApplication.Instance.SaveSettings -= OnSaveState;
            }
        }

        /// <summary>
        /// Called when a page is no longer the active page in a frame.
        /// </summary>
        /// <param name="e">An object that contains the event data.</param>
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // If this is a back navigation, the page will be discarded, so there
            // is no need to save state.
            if (e.NavigationMode != NavigationMode.Back)
            {
                ViewModelBase viewModel = DataContext as ViewModelBase;
                if (viewModel != null)
                {
                    // Save the ViewModel variable in the page's State dictionary.
                    State["ViewModel"] = viewModel;
                }
            }
        }

        /// <summary>
        /// Called when a page becomes the active page in a frame.
        /// </summary>
        /// <param name="e">An object that contains the event data.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // If the page is not constructed it is navigated back from some other page
            // Hence we restore the data context for the page it was stored previously
            if (!_isNewPageInstance)
            {
                object dataContext;
                if (State.TryGetValue("ViewModel", out dataContext))
                {
                    DataContext = dataContext;
                }                
            }
        
            // Set _isNewPageInstance to false. If the user navigates back to this page
            // and it has remained in memory, this value will continue to be false.
            _isNewPageInstance = false;
        }

        /// <summary>
        /// Saves the state.
        /// </summary>
        /// <param name="storageArgs">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        protected virtual void SaveState(DataStoreEventArgs storageArgs)
        {            
        }

        /// <summary>
        /// Loads the state.
        /// </summary>
        /// <param name="storageArgs">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        protected virtual void LoadState(DataStoreEventArgs storageArgs)
        {            
        }        

        /// <summary>
        /// Called when state is to be persisted
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        private void OnSaveState(object sender, DataStoreEventArgs e)
        {
            SaveState(e);
        }

        /// <summary>
        /// Called when state is to be loaded
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        private void OnLoadState(object sender, DataStoreEventArgs e)
        {
            LoadState(e);
        }

        // Private members
        private bool _isNewPageInstance;
    }
}
